package poolserver

import (
	"encoding/binary"
	"net"

	"go.uber.org/zap"
)

/*
读取一个PG的数据包，返回三个值，

	第1个值为读取的字节数，
	第2值为还需要读取的字节数，这通常是数据包比较大，在buf中放不下的情况，
	第3值是错误
*/
func recvMessage(conn net.Conn, buf []byte) (int32, int32, error) {
	var ret int
	var err error
	var pos int32 = 0
	var dataLen int32
	var endPos int32

	bufSize := int32(len(buf))

	//zap.S().Infof("Enter recvMessage")
	//defer zap.S().Infof("Leave recvMessage")

	for {
		//zap.S().Infof("Being read ...")
		ret, err = conn.Read(buf[pos:5])
		//zap.S().Infof("conn.Read return: ret=%d", ret)
		if err != nil {

			conn.Close()
			return pos, 0, err
		}
		pos += int32(ret)
		if pos < 5 {
			continue
		}
		break
	}

	dataLen = int32(binary.BigEndian.Uint32(buf[1:5]))
	if dataLen > bufSize-1 {
		endPos = bufSize
	} else {
		endPos = dataLen + 1
	}

	//zap.S().Infof("dataLen=%d", dataLen);

	for {
		ret, err = conn.Read(buf[pos:endPos])
		if err != nil {
			conn.Close()
			return pos, 0, err
		}
		pos += int32(ret)
		if pos >= endPos {
			break
		}
	}

	if dataLen+1 > bufSize {
		return pos, dataLen + 1 - bufSize, nil
	} else {
		return pos, 0, nil
	}
}

func recvData(conn net.Conn, buf []byte, dataLen int) error {
	var pos = 0
	var ret int
	var err error

	for {
		ret, err = conn.Read(buf[pos:dataLen])
		if err != nil {
			conn.Close()
			return err
		}
		pos += ret
		if pos >= dataLen {
			break
		}
	}
	return nil
}

func sendData(conn net.Conn, buf []byte) (int32, error) {
	var pos int32 = 0
	var ret int
	var err error
	var sendLen = int32(len(buf))

	for pos < sendLen {
		ret, err = conn.Write(buf[pos:sendLen])
		if err != nil {
			zap.S().Infof("Send data error: %s", err.Error())
			conn.Close()
			return pos, err
		}
		pos += int32(ret)
	}
	return pos, nil
}
